﻿using Dting_libraries;
using EasyModbus;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static User_manage.User_Lgon;

namespace Station_interface
{
    public partial class Equipment : UserControl
    {
        #region //属性

        public mySql_class _mySql_class{get;set;}
        public ModbusClient _PLC { get; set; }
        public logicClass _logicClass { get; set; }
        #endregion

        //报警信息添加事件
        public delegate void AlarmAdd_Click(object sender);
        public event AlarmAdd_Click _AlarmAdd_Click;

        //报警信息指定删除事件
        public delegate void Alarmdelete_Click(object sender);
        public event Alarmdelete_Click _Alarmdelete_Click;

        //不良产品记录事件
        public delegate void ProductNG_Click(object sender);
        public event ProductNG_Click _ProductNG_Click;
        object ProductNG_lock = new object();

        //权限显示事件
        public delegate void Counterpoise_Click(object sender);
        public event Counterpoise_Click _Counterpoise_Click;

        //条码生产状态显示事件
        public delegate void BARstate_Click(object sender);
        public event BARstate_Click _BARstate_Click;


        //
        ini_Class _ini_Class = new ini_Class("Config\\sys_data.ini");

        //参数
        public _PlcClass Station = new _PlcClass();
        public class _PlcClass
        {
            public mySql_class _Table_mySql_class;
            public logicClass _logicClass;

            public string _StationName;
            public bool _IsConnected;
            public string _PlcIP;
            public bool Heartbeat = false;          //心跳变量
            public ModbusClient _PLC;


            public int[] Alarm_data;                //报警信息寄存器
            public int[] RunInfo_data;              //运行信息寄存器
            public DataTable inAlarm_DataTable;     //报警信息寄存器
            public DataTable Infobuf;               //运行信息

            public int[] EVAL_Alarm = new int[300];
            public int[] EVAL_info = new int[300];
            public string Quantity = string.Empty;//总产量
            public string OK_quantity = string.Empty;//OK数量
            public string NG_quantity = string.Empty;//NG数量
            public string Cycle = string.Empty;//CT/节拍
            public string Bar_sn = string.Empty;//生产条码
        }

        public Equipment()
        {
            InitializeComponent();
            SetStyle(ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, value: true);
            UpdateStyles();

        }

        public void  Station_init()
        {
            //获取main对象
            Station._PLC = _PLC;
            Station._logicClass = _logicClass;
            Station._StationName = "P1";
            Station._PlcIP = "192.168.0.1";

            //开始连接设备
            Task plc_task = new Task(() =>
            {
                _ConnectPlc();
                Thread.Sleep(10);
            });
            plc_task.Start();

            //初始化EVAL数组


            //获取运行信息
            Station.Infobuf = Deserialize<DataTable>(Application.StartupPath + "\\Config\\" + Station._StationName + "_Info.config");

            //初始化报警列表


            //开始处理逻辑线程任务
            Task _task = new Task(task_work);
            Task _task2 = new Task(task_work2);
            _task.Start();
            _task2.Start();

            Station._logicClass.Info("P1、P2、P3初始化完成......");
        }

        public CancellationTokenSource source = new CancellationTokenSource();

        //设备交互
        private void task_work()
        {
            while (!source.IsCancellationRequested)
            {
                try
                {
                    if (Station._PLC.Connected == false)
                    {
                        ;
                    }
                    else
                    {



                    }
                }
                catch (Exception er)
                {
                    ;
                }

                Thread.Sleep(50);
            }
        }

        //PLC交互
        private void task_work2()
        {
            while (!source.IsCancellationRequested)
            {
                try
                {

                }
                catch (Exception er)
                {
                    ;
                }
            }
        }

        //P1.阻尼器安装
        int logs_a = 0;
        //开始时间
        public DateTime start_time;
        public void P1_task()
        {
            //P1.阻尼器安装
            int[] logData = Station._PLC.ReadHoldingRegisters(5202,30);
            //P1.阻尼器安装
           

            bool Is_Produce = Convert.ToBoolean(logData[0] & (1 << 0)) ? true : false;//D5202.0
            switch (logs_a)
            {
                case 0:
                    if (Is_Produce)
                    {
                        //logs_a = 1;
                        ////获取条码
                        //byte[] bar_str = Station._PLC.ReadHoldingRegisters_byte(5120, 10);
                        //if (bar_str != null)
                        //{
                        //    Station.Bar_sn = Encoding.Default.GetString(bar_str).Trim('\0');

                        //    //开始搜索数据库   条码规则匹配
                        //    if (bar_Equals(Station.Bar_sn))
                        //    {
                        //        //
                        //        int state_bar = 0;
                        //        if (getIsState(StationPLC._PlcName))
                        //        {
                        //            getMySQLdata(Bar_sn, out state_bar);
                        //        }
                        //        else
                        //        {
                        //            state_bar = 4;
                        //        }

                        //        if (state_bar == 1) //正常
                        //        {
                        //            start_time = DateTime.Now;//记录开始时间
                        //            StationPLC._PLC.WriteBit(DataType.Memory, 0, 7051, 0, true);//允许生产
                        //            _logs_Click?.Invoke("工位:" + StationPLC._PlcName + "条码：" + Bar_sn + "允许生产。");
                        //        }
                        //        else if (state_bar == 2) //当前工位已经生产
                        //        {
                        //            P8_dataState = false;
                        //            StationPLC._PLC.WriteBit(DataType.Memory, 0, 7050, 0, true);//当前工位已经生产
                        //            bool strate = Form_warn(Bar_sn);
                        //            _logs_Click?.Invoke("工位:" + StationPLC._PlcName + "当前工位已经生产（重码提示）。");
                        //            if (strate)
                        //            {
                        //                start_time = DateTime.Now;//记录开始时间
                        //                StationPLC._PLC.WriteBit(DataType.Memory, 0, 7050, 4, true);//允许重码生产
                        //                _logs_Click?.Invoke("工位:" + StationPLC._PlcName + "条码：" + Bar_sn + "当前条码为重码，由班组长权限确认后允许的生产。");
                        //                if (StationPLC._PlcName == "P8_工位")
                        //                {
                        //                    P8_dataState = true;
                        //                }
                        //            }
                        //            else
                        //            {
                        //                StationPLC._PLC.WriteBit(DataType.Memory, 0, 7050, 5, true);//不允许重码生产
                        //                _logs_Click?.Invoke("工位:" + StationPLC._PlcName + "当前工位已经生产（重码），不允许生产。");
                        //            }
                        //        }
                        //        else if (state_bar == 3) //上工序未完成
                        //        {
                        //            StationPLC._PLC.WriteBit(DataType.Memory, 0, 7050, 1, true);//上工序未完成
                        //            _logs_Click?.Invoke("工位:" + StationPLC._PlcName + "上工序未完成，不允许生产。");
                        //        }
                        //        else if (state_bar == 4) //未开启验证
                        //        {
                        //            StationPLC._PLC.WriteBit(DataType.Memory, 0, 7051, 0, true);//上工序未完成
                        //            _logs_Click?.Invoke("工位:" + StationPLC._PlcName + "未开启验证，允许生产。");
                        //        }
                        //    }
                        //    else
                        //    {
                        //        _logs_Click?.Invoke("工位:" + StationPLC._PlcName + "当前条码规则不匹配。");
                        //        StationPLC._PLC.WriteBit(DataType.Memory, 0, 7050, 2, true);//不允许生产  规则不匹配
                        //    }
                        //}
                        //else
                        //{
                        //    _logs_Click?.Invoke("工位:" + StationPLC._PlcName + "当前条码规则不匹配。");
                        //    StationPLC._PLC.WriteBit(DataType.Memory, 0, 7050, 2, true);//不允许生产 规则不匹配
                        //}
                    }
                    break;
                case 1:
                    if (!Is_Produce)
                    {
                        //Write_DBit(6202, 0, false);
                        //Write_DBit(6202, 1, false);
                        logs_a = 0;
                    }
                    break;

            }



        }


        

        #region //

        //获取匹配规则
        public bool bar_Equals(string strBar)
        {
            return true;
        }

        //获取数据库是否存在当前条码
        public int getMySQLdata(string Bar_mark, out int state)
        {
            int buf_state = 0;
            Bar_mark = Bar_mark.Replace("\\n", "").Replace(" ", "").Replace("\\t", "").Replace("\\r", "").Replace("\r", "").Replace("\n", "");
            try
            {
                string[] str_data = Station._Table_mySql_class.Mysqllist_Seek("main_station_data_buf", "生产条码", Bar_mark);
                string[] str_data2 = Station._Table_mySql_class.Mysqllist_Seek("main_station_data", "生产条码", Bar_mark);
                if (str_data != null && str_data.Length > 0)
                {
                    switch (Station._StationName)
                    {
                        case "P1_工位":
                            if (str_data[2].Contains("1&"))//当前工位已经生产(重复) 
                            {
                                buf_state = 2;
                            }
                            else if (str_data[2].Equals(""))//可以正常生产
                            {
                                buf_state = 1;
                            }
                            else//上工序未完成
                            {
                                buf_state = 3;
                            }
                            break;
                        case "P2_工位":
                            if (str_data[2].Contains("2&"))//当前工位已经生产(重复)
                            {
                                buf_state = 2;
                            }
                            else if (str_data[2].Contains("1&"))//可以正常生产
                            {
                                buf_state = 1;
                            }
                            else//上工序未完成
                            {
                                buf_state = 3;
                            }
                            break;
                        case "P3_工位":
                            if (str_data[2].Contains("3&"))
                            {
                                buf_state = 2;
                            }
                            //else if (str_data[2].Contains("1&") && str_data[2].Contains("2&"))
                            else if (str_data[2].Contains("2&"))
                            {
                                buf_state = 1;
                            }
                            else
                            {
                                buf_state = 3;
                            }
                            break;
                        case "P4_工位":
                            if (str_data[2].Contains("4&"))
                            {
                                buf_state = 2;
                            }
                            //else if (str_data[2].Contains("1&") && str_data[2].Contains("2&") && str_data[2].Contains("3&"))
                            else if (str_data[2].Contains("3&"))
                            {
                                buf_state = 1;
                            }
                            else
                            {
                                buf_state = 3;
                            }
                            break;
                        case "P5_工位":
                            if (str_data[2].Contains("5&"))
                            {
                                buf_state = 2;
                            }
                            //else if (str_data[2].Contains("1") && str_data[2].Contains("2&") && str_data[2].Contains("3&") && str_data[2].Contains("4&"))
                            else if (str_data[2].Contains("4"))
                            {
                                buf_state = 1;
                            }
                            else
                            {
                                buf_state = 3;
                            }
                            break;
                        case "P6_工位":
                            if (str_data[2].Contains("6&"))
                            {
                                buf_state = 2;
                            }
                            //else if (str_data[2].Contains("1&") && str_data[2].Contains("2&") && str_data[2].Contains("3&") && str_data[2].Contains("4&") && str_data[2].Contains("5&"))
                            else if (str_data[2].Contains("5&"))
                            {
                                buf_state = 1;
                            }
                            else
                            {
                                buf_state = 3;
                            }
                            break;
                        case "P7_工位":
                            if (str_data[2].Contains("7&"))
                            {
                                buf_state = 2;
                            }
                            //else if (str_data[2].Contains("1&") && str_data[2].Contains("2&") && str_data[2].Contains("3&") && str_data[2].Contains("4&") && str_data[2].Contains("5&") && str_data[2].Contains("6&"))
                            else if (str_data[2].Contains("6&"))
                            {
                                buf_state = 1;
                            }
                            else
                            {
                                buf_state = 3;
                            }
                            break;
                        case "P8_工位":
                            if (str_data[2].Contains("8&"))
                            {
                                buf_state = 2;
                            }
                            //else if (str_data[2].Contains("1&") && str_data[2].Contains("2&") && str_data[2].Contains("3&") && str_data[2].Contains("4&") && str_data[2].Contains("5&") && str_data[2].Contains("6&") && str_data[2].Contains("7&"))
                            else if (str_data[2].Contains("7&"))
                            {
                                buf_state = 1;
                            }
                            else
                            {
                                buf_state = 3;
                            }
                            break;
                    }
                }
                else
                {
                    if (Station._StationName == "P1_工位")
                    {
                        buf_state = 1;
                    }
                    else
                    {
                        buf_state = 3;
                    }

                    if (str_data2 != null && str_data2.Length > 0)
                    {
                        switch (Station._StationName)
                        {
                            case "P8_工位":
                                if (str_data2[2].Contains("8&"))
                                {
                                    buf_state = 2;
                                }
                                else if (str_data2[2].Contains("1&") && str_data2[2].Contains("2&") && str_data2[2].Contains("3&") && str_data2[2].Contains("4&") && str_data2[2].Contains("5&") && str_data2[2].Contains("6&") && str_data2[2].Contains("7&"))
                                {
                                    buf_state = 1;
                                }
                                else
                                {
                                    buf_state = 3;
                                }
                                break;
                        }
                    }

                }



                state = buf_state;
                return 0;
            }
            catch (Exception er)
            {
                state = 3;
                return 1;
            }
        }


        //寄存器bit写入操作
        public int Write_DBit(int addr,int bit,bool state)
        {
            try
            {
                int[] logData=null;
                //先读取
                for (int i = 0; i < 3; i++)
                {
                    logData = Station._PLC.ReadHoldingRegisters(addr, 1);
                    if (logData != null && logData.Length > 0)
                    {
                        break;
                    }
                    Thread.Sleep(500);
                }

                if (logData != null && logData.Length > 0)
                {
                    if (state) logData[0] |= (1 << bit);
                    else logData[0] |= ~(1 << bit);

                    //再写入
                    Station._PLC.WriteSingleRegister(addr, logData[0]);
                }
                else { return 2; }

                return 0;
            }
            catch { return 1; }

        }

        //连接plc
        public int _ConnectPlc()
        {
            string messtrNG = "IP:" + Station._PlcIP + " 连接异常，或未找到指定设备";
            string messtrOK = "IP:" + Station._PlcIP + " 连接成功。。。";
            try
            {
                if (IP_ping(station_Interface1.label_IP.Text) == 0)
                {
                    Station._logicClass.Info(messtrNG);
                    Station._IsConnected = false;
                    return 2;
                }
                //判断是否已经连接过，如果有连接过将会断开重连
                if (Station._PLC != null)
                {
                    Station._PLC.Disconnect();
                    Station._PLC = null;
                    Station._IsConnected = false;
                }
                Station._PLC = new  ModbusClient(station_Interface1.label_IP.Text, 102);
                Station._PLC.ConnectionTimeout = 1000;
                if (Station._PLC != null)
                {
                    Station._PLC.Connect();
                    Station._IsConnected = Station._PLC.Connected;
                    Station._logicClass.Info(messtrOK);
                }
                else
                {
                    Station._IsConnected = false;
                    Station._logicClass.Info(messtrNG);
                    return 1;
                }
            }
            catch
            {
                Station._logicClass.Info(messtrNG);
                Station._PLC = null;
                Station._IsConnected = false;
                return 2;
            }

            return 0;
        }

        //断开plc
        public int _ClosePlc()
        {
            string messtrNG = "IP:" + Station._PlcIP + " 断开异常。";
            string messtrOK = "IP:" + Station._PlcIP + " 断开成功。。。";
            try
            {
                if (Station._PLC != null)
                {
                    Station._PLC.Disconnect();
                    Station._PLC = null;
                    Station._IsConnected = false;
                    Station._logicClass.Info(messtrOK);
                }
                else
                {
                    Station._IsConnected = false;
                    Station._logicClass.Info(messtrNG);
                    return 1;
                }
            }
            catch { Station._logicClass.Info(messtrNG); Station._IsConnected = false; return 2; }

            return 0;
        }

        //ping网络
        public int IP_ping(string ip)
        {
            ip = ip.Trim();
            if (ip == string.Empty)
                return 0;

            try
            {
                // 是否 Ping 的通 
                string bufstr = "ping test data";
                PingReply reply = new Ping().Send(ip, 150, Encoding.ASCII.GetBytes(bufstr));
                if (reply.Status == IPStatus.Success)
                {
                    return 1;
                }
                else
                    return 0;
            }
            catch (Exception er)
            {
                return 0;
            }

        }

        // 反序列
        public T Deserialize<T>(string file_path)
        {
            try
            {
                using (FileStream fs = new FileStream(file_path, FileMode.Open))
                {
                    BinaryFormatter binaryFormatter = new BinaryFormatter();
                    return (T)binaryFormatter.Deserialize(fs);
                }
            }
            catch
            {
                return default(T);
            }
        }



        #endregion


    }
}
